﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharpExperiments.Metaprogramming;

namespace CSharpExperiments
{
	public static class Naturals
	{
		public static int Value<N>() where N : Natural, new()
		{
			return typeof(N).Prop<int>("Value");
		}
	}

	public interface Natural {}

	public class Zero : Natural { public static readonly Zero Instance = new Zero(); public static int Value { get { return 0; } } public static implicit operator int(Zero n) { return Value; } }
	public class Nat1 : Zero { public new static readonly Nat1 Instance = new Nat1(); public new static int Value { get { return 1; } } public static implicit operator int(Nat1 n) { return Value; } }
	public class Nat2 : Nat1 { public new static readonly Nat2 Instance = new Nat2(); public new static int Value { get { return 2; } } public static implicit operator int(Nat2 n) { return Value; } }
	public class Nat3 : Nat2 { public new static readonly Nat3 Instance = new Nat3(); public new static int Value { get { return 3; } } public static implicit operator int(Nat3 n) { return Value; } }
	public class Nat4 : Nat3 { public new static readonly Nat4 Instance = new Nat4(); public new static int Value { get { return 4; } } public static implicit operator int(Nat4 n) { return Value; } }
	public class Nat5 : Nat4 { public new static readonly Nat5 Instance = new Nat5(); public new static int Value { get { return 5; } } public static implicit operator int(Nat5 n) { return Value; } }
	public class Nat6 : Nat5 { public new static readonly Nat6 Instance = new Nat6(); public new static int Value { get { return 6; } } public static implicit operator int(Nat6 n) { return Value; } }
	public class Nat7 : Nat6 { public new static readonly Nat7 Instance = new Nat7(); public new static int Value { get { return 7; } } public static implicit operator int(Nat7 n) { return Value; } }
	public class Nat8 : Nat7 { public new static readonly Nat8 Instance = new Nat8(); public new static int Value { get { return 8; } } public static implicit operator int(Nat8 n) { return Value; } }
	public class Nat9 : Nat8 { public new static readonly Nat9 Instance = new Nat9(); public new static int Value { get { return 9; } } public static implicit operator int(Nat9 n) { return Value; } }
	public class Nat10 : Nat9 { public new static readonly Nat10 Instance = new Nat10(); public new static int Value { get { return 10; } } public static implicit operator int(Nat10 n) { return Value; } }
	public class Nat11 : Nat10 { public new static readonly Nat11 Instance = new Nat11(); public new static int Value { get { return 11; } } public static implicit operator int(Nat11 n) { return Value; } }
	public class Nat12 : Nat11 { public new static readonly Nat12 Instance = new Nat12(); public new static int Value { get { return 12; } } public static implicit operator int(Nat12 n) { return Value; } }
	public class Nat13 : Nat12 { public new static readonly Nat13 Instance = new Nat13(); public new static int Value { get { return 13; } } public static implicit operator int(Nat13 n) { return Value; } }
	public class Nat14 : Nat13 { public new static readonly Nat14 Instance = new Nat14(); public new static int Value { get { return 14; } } public static implicit operator int(Nat14 n) { return Value; } }
	public class Nat15 : Nat14 { public new static readonly Nat15 Instance = new Nat15(); public new static int Value { get { return 15; } } public static implicit operator int(Nat15 n) { return Value; } }
	public class Nat16 : Nat15 { public new static readonly Nat16 Instance = new Nat16(); public new static int Value { get { return 16; } } public static implicit operator int(Nat16 n) { return Value; } }
	public class Nat17 : Nat16 { public new static readonly Nat17 Instance = new Nat17(); public new static int Value { get { return 17; } } public static implicit operator int(Nat17 n) { return Value; } }
	public class Nat18 : Nat17 { public new static readonly Nat18 Instance = new Nat18(); public new static int Value { get { return 18; } } public static implicit operator int(Nat18 n) { return Value; } }
	public class Nat19 : Nat18 { public new static readonly Nat19 Instance = new Nat19(); public new static int Value { get { return 19; } } public static implicit operator int(Nat19 n) { return Value; } }
	public class Nat20 : Nat19 { public new static readonly Nat20 Instance = new Nat20(); public new static int Value { get { return 20; } } public static implicit operator int(Nat20 n) { return Value; } }
	public class Nat21 : Nat20 { public new static readonly Nat21 Instance = new Nat21(); public new static int Value { get { return 21; } } public static implicit operator int(Nat21 n) { return Value; } }
	public class Nat22 : Nat21 { public new static readonly Nat22 Instance = new Nat22(); public new static int Value { get { return 22; } } public static implicit operator int(Nat22 n) { return Value; } }
	public class Nat23 : Nat22 { public new static readonly Nat23 Instance = new Nat23(); public new static int Value { get { return 23; } } public static implicit operator int(Nat23 n) { return Value; } }
	public class Nat24 : Nat23 { public new static readonly Nat24 Instance = new Nat24(); public new static int Value { get { return 24; } } public static implicit operator int(Nat24 n) { return Value; } }
	public class Nat25 : Nat24 { public new static readonly Nat25 Instance = new Nat25(); public new static int Value { get { return 25; } } public static implicit operator int(Nat25 n) { return Value; } }
	public class Nat26 : Nat25 { public new static readonly Nat26 Instance = new Nat26(); public new static int Value { get { return 26; } } public static implicit operator int(Nat26 n) { return Value; } }
	public class Nat27 : Nat26 { public new static readonly Nat27 Instance = new Nat27(); public new static int Value { get { return 27; } } public static implicit operator int(Nat27 n) { return Value; } }
	public class Nat28 : Nat27 { public new static readonly Nat28 Instance = new Nat28(); public new static int Value { get { return 28; } } public static implicit operator int(Nat28 n) { return Value; } }
	public class Nat29 : Nat28 { public new static readonly Nat29 Instance = new Nat29(); public new static int Value { get { return 29; } } public static implicit operator int(Nat29 n) { return Value; } }
	public class Nat30 : Nat29 { public new static readonly Nat30 Instance = new Nat30(); public new static int Value { get { return 30; } } public static implicit operator int(Nat30 n) { return Value; } }
	public class Nat31 : Nat30 { public new static readonly Nat31 Instance = new Nat31(); public new static int Value { get { return 31; } } public static implicit operator int(Nat31 n) { return Value; } }
	public class Nat32 : Nat31 { public new static readonly Nat32 Instance = new Nat32(); public new static int Value { get { return 32; } } public static implicit operator int(Nat32 n) { return Value; } }
}
